using System;
using System.Collections;
using System.Collections.Generic;

public class NetworkManager
{   
    private NetConnTCP connTcp = null;
    private NetPacketTCP tcpPacket = null;

    private NetConnUDP connUdp = null;
    private NetPacketUDP udpPacket = null;

    public NetworkManager()
    {
        connTcp = new NetConnTCP();
        tcpPacket = new NetPacketTCP(NetConnTCP.ReadBufferSize,NetConnTCP.SendBufferSize);
        connTcp.reader = tcpPacket;

        connUdp = new NetConnUDP();
        udpPacket = new NetPacketUDP(NetConnTCP.ReadBufferSize,NetConnTCP.SendBufferSize);
        connUdp.reader = udpPacket;
    }
    
    public void Update()
    {
        connTcp.Update();
        connUdp.Update();
    }

    public bool ConnectTcp(string ip,Int32 port)
    {
        connTcp.SetAddress(ip,port);
        return connTcp.Start();
    }

    public void DisconnectTcp()
    {
        connTcp.Stop();
    }

    public void BeginTcpSendStream()
    {
        tcpPacket.BeginSendStream();
    }

    public NetworkInputStream GetTcpSendStream()
    {
        return tcpPacket.GetSendStream();
    }

    public void WriteToTcpSendStream(byte[] buffer, int offset, int count)
    {
        tcpPacket.WriteToSendStream(buffer, offset, count);
    }

    public bool FlushTcpSendStream()
    {
        int count = 0;
        byte[] buf = tcpPacket.FlushSendStream(ref count);
        return connTcp.SendMessage(buf, 0, count);
    }

    public bool SendTcpMessage(byte[] buffer)
    {
        return SendTcpMessage(buffer,0,buffer.Length);
    }

    public bool SendTcpMessage(byte[] buffer,int count)
    {
        return SendTcpMessage(buffer,0,count);
    }

    public bool SendTcpMessage(byte[] buffer, int offset, int count)
    {
        int retCount = 0;
        byte[] data = tcpPacket.PackageSendBuffer(buffer,offset,count,ref retCount);
        if(data != null)
        {
            return connTcp.SendMessage(data,0,retCount);
        }
        else
        {
            return false;
        }
    }

    public void SetTcpConnectedEvent(NetConnTCP.OnConnected handler,bool enable)
    {
        if(enable)
        {
            connTcp.onConnected += handler;
        }
        else
        {
            connTcp.onConnected -= handler;
        }
    }

    public void SetTcpConnectErrorEvent(NetConnTCP.OnConnectError handler,bool enable)
    {
        if(enable)
        {
            connTcp.onConnectError += handler;
        }
        else
        {
            connTcp.onConnectError -= handler;
        }
    }

    public void SetTcpDisconnectedEvent(NetConnTCP.OnDisconnected handler,bool enable)
    {
        if(enable)
        {
            connTcp.onDisconnected += handler;
        }
        else
        {
            connTcp.onDisconnected -= handler;
        }
    }

    public void SetTcpPacketEvent(NetPacketTCP.OnPacket handler,bool enable)
    {
        if(enable)
        {
            tcpPacket.onPacket += handler;
        }
        else
        {
            tcpPacket.onPacket -= handler;
        }
    }


    public bool ConnectUdp(string ip,uint port)
    {
        connUdp.SetAddress(ip,port);
        return connUdp.Start();
    }

    public void DisconnectUdp()
    {
        connUdp.Stop();
    }

    public void BeginUdpSendStream()
    {
        udpPacket.BeginSendStream();
    }

    public NetworkInputStream GetUdpSendStream()
    {
        return udpPacket.GetSendStream();
    }

    public void WriteToUdpSendStream(byte[] buffer, int offset, int count)
    {
        udpPacket.WriteToSendStream(buffer, offset, count);
    }

    public bool FlushUdpSendStream()
    {
        int count = 0;
        byte[] buf = udpPacket.FlushSendStream(ref count);
        return connUdp.SendMessage(buf,count);
    }

    public bool SendUdpMessage(byte[] buffer)
    {
        return SendUdpMessage(buffer,0,buffer.Length);
    }

    public bool SendUdpMessage(byte[] buffer,int count)
    {
        return SendUdpMessage(buffer,0,count);
    }

    public bool SendUdpMessage(byte[] buffer, int offset, int count)
    {
        int retCount = 0;
        byte[] data = udpPacket.PackageSendBuffer(buffer,offset,count,ref retCount);
        if(data != null)
        {
            return connUdp.SendMessage(data,retCount);
        }
        else
        {
            return false;
        }
    }

    public void SetUdpPacketEvent(NetPacketUDP.OnPacket handler,bool enable)
    {
        if(enable)
        {
            udpPacket.onPacket += handler;
        }
        else
        {
            udpPacket.onPacket -= handler;
        }
    }

    public void SetUdpErrorEvent(NetConnUDP.OnError handler,bool enable)
    {
        if(enable)
        {
            connUdp.onError += handler;
        }
        else
        {
            connUdp.onError -= handler;
        }
    }
}